1 /*
2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021
3 License:   [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License].
4 Authors: Marcelo S. N. Mancini
5 
6 	Copyright Marcelo S. N. Mancini 2018 - 2021.
7 Distributed under the CC BY-4.0 License.
8    (See accompanying file LICENSE.txt or copy at
9 	https://creativecommons.org/licenses/by/4.0/
10 */
11 
12 module hip.graphics.mesh;
13 import hip.hiprenderer.renderer;
14 import hip.hiprenderer.shader;
15 import hip.hiprenderer.vertex;
16 import hip.error.handler;
17 import std.traits;
18 
19 class Mesh
20 {
21     protected index_t[] indices;
22     protected void[] vertices;
23     ///Not yet supported
24     bool isInstanced;
25     private bool isBound;
26     HipVertexArrayObject vao;
27     Shader shader;
28     this(HipVertexArrayObject vao, Shader shader)
29     {
30         this.vao = vao;
31         this.shader = shader;
32     }
33     void createVertexBuffer(index_t count, HipBufferUsage usage)
34     {
35         this.vao.createVertexBuffer(count, usage);
36     }
37     void createIndexBuffer(index_t count, HipBufferUsage usage)
38     {
39         this.vao.createIndexBuffer(count, usage);
40     }
41     void sendAttributes()
42     {
43         this.vao.sendAttributes(shader);
44     }
45 
46     void bind()
47     {
48         // if(!this.isBound)
49         // {
50             this.isBound = true;
51             this.shader.bind();
52             this.vao.bind();
53         // }
54         // else assert(false, "Erroneous call to bind.");
55     }
56     void unbind()
57     {
58         // if(this.isBound) 
59         // {
60             this.isBound = false;
61             this.shader.unbind();
62             this.vao.unbind();
63         // }
64         // else assert(false, "Erroneous call to unbind.");
65     }
66 
67     /**
68     *   Will choose between resizing buffer as needed or only updating it.
69     */
70     public void setIndices(index_t[] indices)
71     {
72         if(indices.length <  this.indices.length)
73         {
74             updateIndices(indices);
75             return;
76         }
77         this.indices = indices;
78         this.vao.setIndices(indices);
79     }
80 
81     public void setVertices(const void[] vertices)
82     {
83         if(vertices.length <= this.vertices.length)
84         {
85             updateVertices(vertices);
86             return;
87         }
88         this.vertices = cast(void[])vertices;
89         this.vao.setVertices(vertices);
90     }
91     /**
92     *   Updates the GPU internal buffer by using the buffer sent.
93     *   The offset is always multiplied by the target vertex buffer stride.
94     */
95     public void updateVertices(const void[] vertices, int offset = 0)
96     {
97         this.vao.updateVertices(vertices, offset);
98     }
99     public void updateIndices(const index_t[] indices, int offset = 0)
100     {
101         this.vao.updateIndices(indices, offset);
102     }
103     public void setShader(Shader s){this.shader = s;}
104 
105     /**
106     *   How many indices should it draw
107     */
108     public void draw(T)(T count, HipRendererMode mode, uint offset = 0)
109     {
110         static assert(isUnsigned!T, "Mesh must receive an integral type in its draw");
111         ErrorHandler.assertExit(count < T.max, "Can't draw more than T.max");
112         // if(isVertexArray)
113         // {
114             // HipRenderer.drawVertices()
115         // }
116         //else if(isInstanced)
117         /*
118         {
119             HipRenderer.drawInstanced()
120         }
121         */
122         if(!isBound) bind();
123         HipRenderer.drawIndexed(mode, cast(index_t)count, offset);
124     }
125 
126 }